import { emtionImgIcon, emotionIconLoading, emotionIndexMap, emotionLinkMap } from "./config.js"

export default class MyRichTextInput {
    constructor(containerClass, extendContainerClass = '') {
        this.container = document.querySelector(containerClass);
        this.extendContainer = extendContainerClass ? document.querySelector(extendContainerClass) : null;
        this.boxDom = null;
        this.uploadBtn = null;
        this.modules = [];
        this.observer = new IntersectionObserver(this.observerCallback.bind(this));
    }

    init() {
        this.inputBoxDomGenerate();
        this.modules && this.modules.length && this.initModules();
    }

    inputBoxDomGenerate() {
        const dom = document.createElement("div");
        dom.className = "mTextBoxContainer";
        dom.setAttribute("contenteditable", true);
        this.container.insertBefore(dom, this.container.firstChild);
        this.container.focus();
        this.boxDom = dom;
    }

    contentGet() {
        return this.boxDom.innerHTML;
    }

    contentSet(html) {
        this.boxDom.innerHTML = html;
        this.setFocusFun(this.boxDom);
    }

    use(extendsName) {
        this.modules.push('use' + extendsName.replace(/\w/, $ => $.toUpperCase()));
    }

    initModules() {
        this.modules.map(handle => {
            this[handle]();
        });
    }

    useEmotion() {
        const _this = this;
        const emotionIcon = document.createElement("div");
        emotionIcon.className = "mRichTextEmotion mRichTextIcon";
        emotionIcon.onclick = function () {
            const isActive = Array.prototype.includes.call(this.classList, 'active');
            this.classList[isActive ? 'remove' : 'add']('active');
            _this.richTextEmotionContainerShow(this);
            _this.setFocusFun(_this.boxDom);
        }
        const emotionImgContainer = document.createElement("div");
        emotionImgContainer.className = "mRichTextEmotionContainer";
        const emotionImgNav = document.createElement("div");
        emotionImgNav.className = "mRichTextEmotionNav";
        for (let i = 0; i < emtionImgIcon.length; i++) {
            const emotionImgNavItem = document.createElement("div");
            emotionImgNavItem.className = `mRichTextEmotionNavItem ${i === 0 ? 'active' : ''}`;
            const emotionImgNavImg = document.createElement("img");
            emotionImgNavImg.setAttribute('src', emtionImgIcon[i]);
            emotionImgNavItem.appendChild(emotionImgNavImg);
            emotionImgNav.appendChild(emotionImgNavItem);
        }
        const emotionImgList = document.createElement("div");
        emotionImgList.className = "mRichTextEmotionImgList";
        emotionImgContainer.appendChild(emotionImgNav);
        emotionImgContainer.appendChild(emotionImgList);
        emotionIcon.appendChild(emotionImgContainer);
        this.extendContainer.appendChild(emotionIcon);
        window.addEventListener('click', function () {
            emotionIcon.classList.remove('active');
        }, false);
        this.container.addEventListener('click', function (ev) {
            ev.stopPropagation();
        });
        this.emotionContainer(emotionImgList);
        this.emotionNavHandle(emotionImgNav, emotionImgList);
    }

    richTextEmotionContainerShow(emotionBtn) {
        const emotionImgContainerDom = emotionBtn.querySelector(".mRichTextEmotionContainer")
        const emotionImgContainerHeight = emotionImgContainerDom.offsetHeight;
        const screenHeight = document.documentElement.clientHeight;
        const reactObj = emotionBtn.getBoundingClientRect();
        const isScreenOverFlow = emotionImgContainerHeight + reactObj.top > screenHeight;
        emotionImgContainerDom.classList[isScreenOverFlow ? 'add' : 'remove']("isTopShow");
    }

    setFocusFun(ele) {
        if (window.getSelection) {
            ele.focus();
            var range = window.getSelection();
            range.selectAllChildren(ele);
            range.collapseToEnd();
        } else if (document.selection) {
            var range = document.selection.createRange();
            range.moveToElementText(ele);
            range.collapse(false);
            range.select();
        }
    }

    emotionNavHandle(emotionImgNav, emotionImgList) {
        const _this = this;
        const oNavs = emotionImgNav.querySelectorAll('.mRichTextEmotionNavItem');
        Array.prototype.map.call(oNavs, (nav, index) => {
            nav.onclick = function (ev) {
                ev.stopPropagation();
                Array.prototype.map.call(oNavs, item => item.classList.remove('active'));
                this.classList.add('active');
                _this.emotionContainer(emotionImgList, index);
            }
        })
    }

    emotionContainer(emotionImgList, navIndex = 0) {
        emotionImgList.innerHTML = "";
        const emotionImgItem = src => {
            const imgWrap = document.createElement("div");
            imgWrap.className = "mRichTextEmotionImgItem";

            const imgDom = document.createElement("img");
            imgDom.setAttribute('src', emotionIconLoading);
            imgDom.setAttribute('data-src', src);

            imgWrap.appendChild(imgDom);
            emotionImgList.appendChild(imgWrap);

            this.observer.observe(imgWrap);
        }
        const emotionLinkNumMap = [
            index => index > 9 ? "" + index : "0" + index,
            index => index,
            index => `download(${index})`,
        ];
        Array(emotionIndexMap[navIndex]).fill('').map((item, index) => {
            index++;
            const num = emotionLinkNumMap[navIndex](index);
            const src = `${emotionLinkMap[navIndex]['link']}${num}${emotionLinkMap[navIndex]['ext']}`
            emotionImgItem(src);
        })
    }

    observerCallback(entries) {
        const _this = this;
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const t = entry.target;
                const imgDom = t.querySelector('img');
                const _src = imgDom.getAttribute('data-src');
                imgDom.setAttribute('src', _src);
                imgDom.onclick = function (ev) {
                    ev.stopPropagation();
                    _this.imageInsert(_src);
                    _this.boxDom.focus();

                }
            }
        })
    }

    imageInsert(src) {
        if (window.getSelection) {
            var sel = window.getSelection();
            var range = sel.getRangeAt(0);
            var img = new Image();
            range.deleteContents();
            img.src = src;
            range.insertNode(img);
            range.collapse(false);
        }
    }

    useUpload() {
        const uploadIcon = document.createElement("div");
        uploadIcon.className = "mRichTextUploadIcon mRichTextIcon";

        const anchorClass = "mRichTextUploadInp";
        const oInput = document.createElement("input");
        oInput.setAttribute("type", "file");
        oInput.className = anchorClass;
        oInput.id = anchorClass;
        uploadIcon.appendChild(oInput);

        const oLabel = document.createElement("label");
        oLabel.className = "mRichTextUploadLabel";
        oLabel.setAttribute('for', anchorClass);
        uploadIcon.appendChild(oLabel);

        this.extendContainer.appendChild(uploadIcon);
        this.uploadBtn = oInput;
    }

    fileInsert(uploadApi) {
        const _this = this;
        return new Promise(resolve => {
            this.uploadBtn.onchange = async function (ev) {
                const { files } = ev.target;
                const src = await uploadApi(files);
                _this.setFocusFun(_this.boxDom);
                _this.imageInsert(src);
                resolve(src);
            }
        })
    }
}